//
//  UIImageView+LK.m
//  修改自江大大的库
//
//  Created by ljh on 14-2-13.
//  Modified by hehe
//  Copyright (c) 2014年 ------. All rights reserved.
//

#import "UIImageView+LK.h"

static char imageURLKey;
static char imageStatusKey;
static char imageTapEventKey;
static char imageLoadedModeKey;
static char imagePlaceholdderModeKey;
static char placeholderImageNameKey;
static char failureImageNameKey;
static char isHideProgressKey;
static char statusChangeKey;
static char imageReloadCountKey;

@implementation UIImageView (LK)

#pragma mark - added property

-(UIViewContentMode)loadedViewContentMode
{
    NSNumber *value = objc_getAssociatedObject(self, &imageLoadedModeKey);
    if(value == nil){
        return -1;
    }
    return [value intValue];
}

-(void)setLoadedViewContentMode:(UIViewContentMode)loadedViewContentMode
{
    objc_setAssociatedObject(self, &imageLoadedModeKey, @(loadedViewContentMode), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(UIViewContentMode)placeholderContentMode
{
    NSNumber *value = objc_getAssociatedObject(self, &imagePlaceholdderModeKey);
    if(!value){
        return UIViewContentModeCenter;
    }
    return [value intValue];
}

-(void)setPlaceholderContentMode:(UIViewContentMode)placeholderContentMode
{
    objc_setAssociatedObject(self, &imagePlaceholdderModeKey, @(placeholderContentMode), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(NSString *)placeholderImageName
{
    NSString *value = objc_getAssociatedObject(self, &placeholderImageNameKey);
    return value;
}

-(void)setPlaceholderImageName:(NSString *)placeholderImageName
{
    objc_setAssociatedObject(self, &placeholderImageNameKey, placeholderImageName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(NSString *)failureImageName
{
    NSString *value = objc_getAssociatedObject(self, &failureImageNameKey);
    return value;
}

-(void)setFailureImageName:(NSString *)failureImageName
{
    objc_setAssociatedObject(self, &failureImageNameKey, failureImageName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(BOOL)isHideProgress
{
    NSNumber *number = objc_getAssociatedObject(self, &isHideProgressKey);
    return [number boolValue];
}

-(void)setIsHideProgress:(BOOL)isHideProgress
{
    NSNumber *number = [NSNumber numberWithBool:isHideProgress];
    objc_setAssociatedObject(self, &isHideProgressKey, number, OBJC_ASSOCIATION_RETAIN);
}

- (LKImageViewStatus)status
{
    NSNumber *value = objc_getAssociatedObject(self, &imageStatusKey);
    if (value){
        return [value intValue];
    }
    return LKImageViewStatusNone;
}

- (void)setStatus:(LKImageViewStatus)status
{
    objc_setAssociatedObject(self, &imageStatusKey, @(status), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if(self.statusChangeBlock){
        self.statusChangeBlock(status);
    }
}

-(void (^)(LKImageViewStatus))statusChangeBlock
{
    return objc_getAssociatedObject(self, &statusChangeKey);
}

-(void)setStatusChangeBlock:(void (^)(LKImageViewStatus))statusChangeBlock
{
    objc_setAssociatedObject(self, &statusChangeKey, statusChangeBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(int)reloadCount
{
    NSNumber *value = objc_getAssociatedObject(self, &imageReloadCountKey);
    return [value intValue];
}

-(void)setReloadCount:(int)count
{
    objc_setAssociatedObject(self, &imageReloadCountKey, @(count), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - method
-(NSURL*)lk_URLWithImageURL:(id)imageURL
{
    if ([imageURL isKindOfClass:[NSString class]]){
        if([imageURL hasPrefix:@"http"]||[imageURL hasPrefix:@"ftp"]){
            imageURL = [NSURL URLWithString:imageURL];
        }
        else{
            imageURL = [NSURL fileURLWithPath:imageURL];
        }
    }
    if ([imageURL isKindOfClass:[NSURL class]] == NO){
        imageURL = nil;
    }
    return imageURL;
}

- (void)setImageURLFromCache:(id)imageURL
{
    //[self lk_loadTapEvent];
    self.status = LKImageViewStatusLoaded;
    
    imageURL = [self lk_URLWithImageURL:imageURL];
    objc_setAssociatedObject(self, &imageURLKey, imageURL, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (void)setImageURL:(id)imageURL
{
    [self lk_setImageURL:imageURL];
}

-(void)lk_setImageURL:(id)imageURL
{
    //[self lk_loadTapEvent];
    
    imageURL = [self lk_URLWithImageURL:imageURL];
    if (self.lk_imageURL && self.image && self.image.duration == 0 && self.status == LKImageViewStatusLoaded && imageURL){
        if([[self.lk_imageURL absoluteString] isEqualToString:[imageURL absoluteString]]){
            ///相同的图片URL 就不在设置了
            return;
        }
    }
    
    objc_setAssociatedObject(self, &imageURLKey, imageURL, OBJC_ASSOCIATION_COPY_NONATOMIC);
    if (imageURL){
        [self setReloadCount:0];
        [self reloadImageURL];
    }
    else{
        [self cancelCurrentImageRequest];
        [self lk_showImageWithName:self.placeholderImageName];
        self.status = LKImageViewStatusNone;
    }
}

static char tapEventLoadedKey;
- (void)lk_loadTapEvent
{
    UITapGestureRecognizer* tap = objc_getAssociatedObject(self, &tapEventLoadedKey);
    if (tap == nil){
        self.userInteractionEnabled = YES;
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(lk_handleTapEvent:)];
        [self addGestureRecognizer:tap];
        objc_setAssociatedObject(self, &tapEventLoadedKey,tap, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
}

-(BOOL)lk_hasLoadedTapEvent
{
    id tapObj = objc_getAssociatedObject(self, &tapEventLoadedKey);
    return tapObj != nil;
}

-(id)imageURL
{
    return [self lk_imageURL];
}

- (id)lk_imageURL
{
    return objc_getAssociatedObject(self, &imageURLKey);
}

-(void)lk_init_imageview
{
    [self cancelCurrentImageRequest];
    self.image = nil;
    
    if(self.loadedViewContentMode < 0){
        self.loadedViewContentMode = self.contentMode;
    }
}

- (void)reloadImageURL
{
    id imageURL = self.lk_imageURL;
    
    [self lk_init_imageview];
    self.contentMode = self.placeholderContentMode;
    self.status = LKImageViewStatusLoading;
    
    @weakify(self);
    [self setImageWithURL:imageURL placeholder:[UIImage imageNamed:self.placeholderImageName]  options:YYWebImageOptionSetImageWithFadeAnimation | YYWebImageOptionProgressiveBlur progress:^(NSInteger receivedSize, NSInteger expectedSize) {
        
    } transform:^UIImage *(UIImage *image, NSURL *url) {
        return image;
    } completion:^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
        @strongify(self);
         if (image){
             self.status = LKImageViewStatusLoaded;
             if(image.duration == 0){
                 if(self.loadedViewContentMode > 0 && self.contentMode != self.loadedViewContentMode)
                 {
                     self.contentMode = self.loadedViewContentMode;
                     [self setNeedsDisplay];
                 }
             }
         }
         else{
             if (error){
                 int reloadCount = [self reloadCount];
                 if(reloadCount < 2){
                     [self setReloadCount:reloadCount+1];
                     [self reloadImageURL];
                     return ;
                 }
                 [self lk_showImageWithName:self.failureImageName];
                 self.status = LKImageViewStatusFail;
             }
             else{
//                 [self lk_showImageWithName:self.placeholderImageName];
                 self.status = LKImageViewStatusNone;
             }
         }
    }];
}

-(void)lk_showImageWithName:(NSString*)name
{
    UIImage *image = [UIImage imageNamed:name];
    if (self.bounds.size.width < image.size.width || self.bounds.size.height < image.size.height){
        self.contentMode = UIViewContentModeScaleAspectFit;
    }
    else{
        self.contentMode = UIViewContentModeCenter;
    }
    self.image = image;
    [self setNeedsDisplay];
}

- (void)setOnTouchTapBlock:(void (^)(UIImageView *))onTouchTapBlock
{
    [self lk_loadTapEvent];
    objc_setAssociatedObject(self, &imageTapEventKey, onTouchTapBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (void (^)(UIImageView *))onTouchTapBlock
{
    return objc_getAssociatedObject(self, &imageTapEventKey);
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
//    if(self.lk_imageURL == nil && [self lk_hasLoadedTapEvent]){
//        return NO;
//    }
    LKImageViewStatus status = self.status;
    if (status == LKImageViewStatusClickDownload || status == LKImageViewStatusFail){
        return [super pointInside:point withEvent:event];
    }
    
    if (self.lk_imageURL && self.onTouchTapBlock == nil){
        return NO;
    }
    return [super pointInside:point withEvent:event];
}

- (void)lk_handleTapEvent:(UITapGestureRecognizer *)sender
{
    if (self.onTouchTapBlock){
        self.onTouchTapBlock(self);
    }
}

@end
